﻿using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using TK_CSLua.ILAnalyze;

namespace CSLua
{
	// Token: 0x02000021 RID: 33
	public class BuildFileContext
	{
		// Token: 0x06000130 RID: 304 RVA: 0x000086F8 File Offset: 0x000068F8
		public BuildFileContext(LuaType luaType, CodeWriter writer)
		{
			this.luaType = luaType;
			this.writer = writer;
			this.mainTypeDef = luaType.ILTypeDef;
		}

		// Token: 0x06000131 RID: 305 RVA: 0x0000875C File Offset: 0x0000695C
		public void addSelfMethodCache(string method)
		{
			this.cachedSelfMethods.Add(method);
		}

		// Token: 0x06000132 RID: 306 RVA: 0x0000876C File Offset: 0x0000696C
		public string buildTailCode()
		{
			CodeWriter header = this.writer.push();
			header.commentLine("-----------");
			header.commentLine("-本类型里被引用函数的赋值");
			foreach (string method in this.cachedSelfMethods)
			{
				header.assignLocal(method, header.push().get(this.getTypeDefineName(this.mainTypeDef), method).pop()).nextLine();
			}
			header.commentLine("-----------");
			return header.pop();
		}

		// Token: 0x06000133 RID: 307 RVA: 0x00008818 File Offset: 0x00006A18
		public string toSimpleName(string prefix, string fullName)
		{
			string cachedSimpleName;
			if (!this.simpledNameDict.TryGetValue(fullName, out cachedSimpleName))
			{
				string[] items = fullName.Split(new char[]
				{
					'_'
				});
				string[] array = items;
				string simpleName = prefix + array[array.Length - 1];
				if (this.simpledNameDict.ContainsValue(simpleName))
				{
					simpleName = fullName;
				}
				this.simpledNameDict.Add(fullName, simpleName);
				return simpleName;
			}
			return cachedSimpleName;
		}

		// Token: 0x06000134 RID: 308 RVA: 0x00008875 File Offset: 0x00006A75
		public string getMethodName(MethodReference refe)
		{
			return OverloadAnalyzer.getMethodName(refe);
			/*if (this.isLuaType(refe.DeclaringType))
			{
				return OverloadAnalyzer.getMethodName(refe);
			}
			return refe.luaIdentifier();*/
		}

		// Token: 0x06000135 RID: 309 RVA: 0x000088AB File Offset: 0x00006AAB
		public bool isLuaType(TypeReference type)
		{
			return type.isLuaType();
		}

		// Token: 0x06000136 RID: 310 RVA: 0x000088B3 File Offset: 0x00006AB3
		public string getCSLLibs(string libName)
		{
			this.cslLibs.Add(libName);
			return libName;
		}

		// Token: 0x06000137 RID: 311 RVA: 0x000088C3 File Offset: 0x00006AC3
		public bool isNativeCSType(TypeReference type)
		{
			return !type.isLuaType();
		}

		// Token: 0x06000138 RID: 312 RVA: 0x000088CE File Offset: 0x00006ACE
		public bool IsNewValueFunc(MemberReference memberRef)
		{
			return this.luaType.LuaAssembly.IsNewValueFunc(memberRef);
		}

		// Token: 0x06000139 RID: 313 RVA: 0x000088E1 File Offset: 0x00006AE1
		public bool IsImmutableValueFunc(MemberReference memberRef)
		{
			return this.luaType.LuaAssembly.IsImmutableValueFunc(memberRef);
		}

		// Token: 0x0600013A RID: 314 RVA: 0x000088F4 File Offset: 0x00006AF4
		public bool isRebind(TypeReference type)
		{
			return this.luaType.LuaAssembly.IsRebindType(type);
		}

		// Token: 0x0600013B RID: 315 RVA: 0x00008907 File Offset: 0x00006B07
		internal bool checkRebindMethod(MethodReference methodRef)
		{
			return !this.isRebind(methodRef.DeclaringType) || this.luaType.LuaAssembly.GetRebindMethod(methodRef) != null;
		}

		// Token: 0x0600013C RID: 316 RVA: 0x0000892D File Offset: 0x00006B2D
		public string getStaticFieldId(FieldReference refe)
		{
			return this.getTypeId(refe.DeclaringType, false) + "." + refe.luaIdentifier();
		}

		// Token: 0x0600013D RID: 317 RVA: 0x0000894C File Offset: 0x00006B4C
		public string getTypeDefineName(TypeReference refe)
		{
			return refe.luaIdentifier();
		}

		// Token: 0x0600013E RID: 318 RVA: 0x00008954 File Offset: 0x00006B54
		internal bool isForceUnvirtual(MethodReference methodRef)
		{
			return this.luaType.LuaAssembly.isForceUnvirtual(methodRef);
		}

		// Token: 0x0600013F RID: 319 RVA: 0x00008968 File Offset: 0x00006B68
		public string getNativeTypeName(TypeReference refe)
		{
			if (!this.luaType.LuaAssembly.IsRebindType(refe) && !this.luaType.LuaAssembly.isRenameType(refe))
			{
				return this.getCSLLibs(CSLLibs.TKNS) + "." + BuilderUtils.GetTypeFullname(refe.Resolve(), true);
			}
			TypeDefinition typeDef = this.luaType.LuaAssembly.ResloveType(refe);
			string fullTypeName = this.luaType.LuaAssembly.ResloveTypeName(typeDef);
			if (fullTypeName == null)
			{
				fullTypeName = BuilderUtils.GetTypeFullname(typeDef, true);
			}
			return fullTypeName;
		}

		// Token: 0x06000140 RID: 320 RVA: 0x000089F0 File Offset: 0x00006BF0
		internal string defaultValueCode(TypeReference aType)
		{
			if (aType.isIntType())
			{
				return "0";
			}
			if (aType.isFloatType())
			{
				return "0.0";
			}
			if (aType.isTypeOf<bool>())
			{
				return "false";
			}
			if (aType.Resolve() != null && aType.Resolve().IsEnum)
			{
				return "0";
			}
			if (aType.IsValueType)
			{
				return this.getCSLLibs("CSLNew") + "(" + this.getTypeId(aType, false) + ")";
			}
			return this.writer.tokens.nil;
		}

		// Token: 0x06000141 RID: 321 RVA: 0x00008A80 File Offset: 0x00006C80
		public string getTypeIdForDefine(TypeReference refe)
		{
			if (!this.isLuaType(refe))
			{
				return this.getTypeId(refe, false);
			}
			TypeDefinition decFileType;
			string nestPath;
			BuilderUtils.GetTypeNestPath(refe.Resolve(), out decFileType, out nestPath);
			if (string.IsNullOrEmpty(nestPath))
			{
				return this.getCSLLibs(CSLLibs.CSLRequireType) + "('" + BuilderUtils.GetTypeFullname(decFileType, true) + "')";
			}
			return string.Concat(new string[]
			{
				this.getCSLLibs(CSLLibs.CSLRequireType),
				"('",
				BuilderUtils.GetTypeFullname(decFileType, true),
				"','",
				nestPath,
				"')"
			});
		}

		// Token: 0x06000142 RID: 322 RVA: 0x00008B18 File Offset: 0x00006D18
		public string getTypeId(TypeReference refe, bool global = false)
		{
			if (refe.IsGenericParameter || (refe.IsArray && refe.GetElementType().IsGenericParameter))
			{
				return refe.ToString();
			}
			if (this.isLuaType(refe))
			{
				TypeDefinition def = refe.Resolve();
				string luaTypeName = BuilderUtils.GetTypeFullname(def, false);
				if (def.GetCustomAttributeArguments(BuildConfig.nativeAttribute, ref luaTypeName))
					return luaTypeName;
				if (!global && this.isLocalFileType(def))
				{
					return this.getTypeDefineName(def);
				}
				if (def.hasAttributes(BuildConfig.protoAttribute))
				{
					return this.getCSLLibs("CSLTypes") + "['" + def.FullName + "']";
				}
				return this.getCSLLibs("CSLTypes") + "." + luaTypeName;
			}
			string id;
			if (!this.reftypes.TryGetValue(refe, out id))
			{
				id = this.getNativeTypeName(refe).Replace('.', '_');
				id = this.toSimpleName("T_", id);
				this.reftypes.Add(refe, id);
			}
			return id;
		}

		// Token: 0x06000143 RID: 323 RVA: 0x00008C38 File Offset: 0x00006E38
		private bool isLocalFileType(TypeDefinition def)
		{
			while (def != null)
			{
				if (def.isEquals(this.mainTypeDef))
				{
					return true;
				}
				def = def.DeclaringType;
			}
			return false;
		}

		// Token: 0x06000144 RID: 324 RVA: 0x00008C58 File Offset: 0x00006E58
		internal bool isLambdaType(TypeReference t)
		{
			TypeDefinition def = t.Resolve();
			return def != null && def.IsNestedPrivate && def.getAttribute("System.Runtime.CompilerServices.CompilerGeneratedAttribute") != null;
		}

		// Token: 0x04000090 RID: 144
		private const string CompilerGeneratedAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute";

		// Token: 0x04000091 RID: 145
		public const string funcSimpleNamePrefix = "F_";

		// Token: 0x04000092 RID: 146
		public const string typeSimpleNamePrefix = "T_";

		// Token: 0x04000093 RID: 147
		public Dictionary<MethodReference, string> refmethods = new Dictionary<MethodReference, string>();

		// Token: 0x04000094 RID: 148
		public Dictionary<TypeReference, string> reftypes = new Dictionary<TypeReference, string>();

		// Token: 0x04000095 RID: 149
		public HashSet<string> cslLibs = new HashSet<string>();

		// Token: 0x04000096 RID: 150
		private TypeDefinition mainTypeDef;

		// Token: 0x04000097 RID: 151
		private LuaType luaType;

		// Token: 0x04000098 RID: 152
		public Dictionary<string, string> simpledNameDict = new Dictionary<string, string>();

		// Token: 0x04000099 RID: 153
		public HashSet<string> cachedSelfMethods = new HashSet<string>();

		// Token: 0x0400009A RID: 154
		private CodeWriter writer;
	}
}
